unit u_engine;

interface

uses


u_form,
u_input,
u_camera,
u_player,
u_mesh,
u_menu,
u_surcouf,
u_asus,
u_load,
u_jresau,
u_partic,
u_sound,
u_senar,
sysutils,
u_resennemi,
u_ia,
u_gamemenu,
u_menu_in_game,
System.Windows.Forms,
Microsoft.DirectX,
Microsoft.DirectX.Direct3D,
Microsoft.DirectX.Direct3DX,
System.Drawing;


type



c_engine = class
  private

    mycam: c_camera;
    myinput: c_Input;
    mysound: c_sound;
    map: t_map_obj;
    menu_mesh : Mesh;
    m_espion : mesh;
    t_espion : texture;
    m_kamikaze : mesh;
    t_kamikaze : texture;
    m_warrior : mesh;
    t_warrior : texture;

  public


    constructor create;
    procedure resetdevice(sender: TObject; e: EventArgs);
    procedure render;
    procedure affiche_mesh;
    procedure dispose;
    procedure refresh_mobs;
    procedure affiche_car_en;



end;

var
  myform: c_form;
  mymesh: c_mesh;
  myplayer : c_player;
  mymenu : c_menu;
  myennemis : c_ennemis;
  mygamemenu : c_gamemenu; // mypartic suppr
  mymenu_in_game: c_menu_in_game;
  mysurcouf: c_surcouf;
  mysenar: c_senar;


implementation

uses u_astar;


constructor c_engine.create;
var
  mat: array of ExtendedMaterial;
begin
  inherited create;
  myform := c_form.create;
  mycam := c_camera.Create;
  myennemis := c_ennemis.create;
//  myparticle := TParticle.Create(myform._3D_device);

  Borland.Delphi.System.Include(myform._3D_device.DeviceReset, resetdevice);
  self.resetdevice( myform._3D_device, nil);
  myform.min := 0;

  myform.phi := 0;
  myform.zoom := 4;
//  myform.activeetage := mymesh.dep_eta.etage;


  m_espion := mesh.FromFile('meshes\pipi',meshflags.SystemMemory,myform._3D_device,mat);
  t_espion := textureloader.FromFile(myform._3D_device,'meshes\' + mat[0].TextureFilename);
  m_kamikaze := mesh.FromFile('meshes\Zobi la mouche',meshflags.SystemMemory,myform._3D_device,mat);
  t_kamikaze := textureloader.FromFile(myform._3D_device,'meshes\' + mat[0].TextureFilename);
  m_warrior := mesh.FromFile('meshes\caca',meshflags.SystemMemory,myform._3D_device,mat);
  t_warrior := textureloader.FromFile(myform._3D_device,'meshes\' + mat[0].TextureFilename);


  menu_mesh := Mesh.FromFile('sol.x', MeshFlags.SystemMemory, myform._3D_device);
  mysenar := c_senar.create(myform._3D_device);

end;



procedure c_engine.resetdevice(sender: tObject; e: EventArgs);
var
  mat: array of ExtendedMaterial;
  i, j: integer;
  matlengh: integer;
  bit: bitmap;
begin
  myform._3D_device := device(sender);
  myform._3D_device.RenderState.CullMode := Cull.None;
  myform._3D_device.RenderState.Lighting := false;
  myform._3D_device.RenderState.ZBufferEnable := true;
  myform._3D_device.RenderState.Ambient := Color.get_black;
end;

//modif

procedure c_engine.render;
var j, i, k : integer;
  j_res : t_player;
  t_enn: t_ennemi;
  begin
    if myform._3D_device = nil then
      exit;
    if myform.fpause then
      exit;

    myform._3D_device.Clear(clearflags.Target or clearflags.ZBuffer, color.black, 1, 0);
    myform._3D_device.BeginScene;



        if mymenu.show_menu then
          begin
            mycam := c_camera.Create;
//            myform._3D_device.Transform.World := myform._3D_device.Transform.World.Rotationx(-pi / 4)*
//                    myform._3D_device.Transform.World.Rotationz(mymenu.get_angle) *
//                    myform._3D_device.Transform.World.Scaling(2, 3, 0) *
//                    myform._3D_device.Transform.World.translation(-1, -1, 0);
//              myform._3D_device.SetTexture(0, mymenu.show_texture(myform.m_x , myform.M_y));


            mymenu.show_texture(myform.m_x, myform.m_y);
            mymenu.render_text;
//            mymenu.render_sprite;
          end
        else
        begin

    if  not mygamemenu._visible then
      begin
        myform.zoom := myform.zoom -
          mycam.initcam(myform._3D_device,
                        myform._width,
                        myform._height,
                        myform.phi,
                        myform.teta,
                        myform.zoom,
                        myplayer.get_x,
                        myplayer.get_y);
          if myform.zoom < 2 then
            myform.zoom := 2;

if (myplayer.prout_etage.monte) then
    begin
      if (((myplayer.get_x) >= (myplayer.prout_etage.x-1)) and ((myplayer.get_x) <= (myplayer.prout_etage.x+1))) and (((myplayer.get_y) >= (myplayer.prout_etage.y-1)) and ((myplayer.get_y) <= (myplayer.prout_etage.y+1))) then
      begin
        if not mysurcouf.passe then
          begin
            mysurcouf.visible := true;
            myplayer.prout_etage.sur := true;
            myplayer.selection_pos.exist := false;
          end;
        if mysurcouf.visible then
          begin
            mysurcouf.affi_menu(myform.Height, myform.Width, myplayer.tab_contenu);
            mysurcouf.sur_bouton(myform.m_x, myform.m_y, myform.Width, myform.Height);
          end;
        if not myplayer.prout_etage.sur then
          begin
            myplayer.etage := myplayer.etage + 1;
            myplayer.prout_etage.monte := false;
            myplayer.prout_etage.sur := false;
            for k := low(mymesh.tab_mesh) to high(mymesh.tab_mesh) do
              begin
                mymesh.tab_mesh[k].texture.Dispose;
                mymesh.tab_mesh[k].mesh.Dispose;
              end;
            mymesh.loader_mesh(myform._3D_device,myplayer.etage);
            myennemis.dispose;
            myennemis.Free;
            myennemis := C_ennemis.Create;
            myennemis.tableaux(myplayer.etage,mymesh.map2);
            mysurcouf.passe := false;
          end;
      end;
    end
  else
    begin
      if (myplayer.prout_etage.descend) then
        begin
      if (((myplayer.get_x) >= (myplayer.prout_etage.x-1)) and ((myplayer.get_x) <= (myplayer.prout_etage.x+1))) and (((myplayer.get_y) >= (myplayer.prout_etage.y-1)) and ((myplayer.get_y) <= (myplayer.prout_etage.y+1))) then
          begin
            myplayer.etage := myplayer.etage - 1;
            myplayer.prout_etage.descend := false;
            myplayer.selection_pos.exist := false;
            for k := low(mymesh.tab_mesh) to high(mymesh.tab_mesh) do
              begin
                mymesh.tab_mesh[k].texture.Dispose;
                mymesh.tab_mesh[k].mesh.Dispose;
              end;
            mymesh.loader_mesh(myform._3D_device,myplayer.etage);
            myennemis.dispose;
            myennemis.Free;
            myennemis := C_ennemis.Create;
            myennemis.tableaux(myplayer.etage,mymesh.map2);
          end;
        end
    end;


    if not mysurcouf.visible then
      begin
          self.affiche_mesh;


          if myplayer.game_type = 'o' then
            myennemis.appel_champ(myplayer.etage, mymesh.taillex, mymesh.tailley, myplayer.get_x,myplayer.get_y, mymesh.map1,mymesh.map2);
          if myplayer.game_type = 's' then
            begin
              myplayer.myreseau.renvoi_tab_coord(j_res);
              myennemis.appel_champres(myplayer.etage, mymesh.taillex, mymesh.tailley, j_res, mymesh.map1, mymesh.map2);
            end;








           myplayer.render_player(myform._3D_device);
           myplayer.player_mesh.DrawSubset(0);
           myplayer.mychat.chat_render;




           //Affichage des joueurs en réseau
           myplayer.myreseau.get_all_info(j_res);
           if Length(j_res) <> 0 then
             for i := 0 to Length(j_res) - 1 do
              begin
                myform._3D_device.Transform.World :=
                            myform._3D_device.Transform.World.RotationZ(math.pi) *
                            myform._3D_device.Transform.World.RotationX(- math.pi / 2) *
                            myform._3D_device.Transform.World.Scaling(0.0023, 0.0023,0.0023) *
                            myform._3D_device.Transform.World.Translation(j_res[i].x, 0.6, j_res[i].y);
                myform._3D_device.SetTexture(0, myplayer.player_texture);
                myplayer.player_mesh.DrawSubset(0);
              end;

           if myplayer.game_type = 'c' then
            begin
              myplayer.myreseauennemis.get_ennemi_by_typ('Espion', t_enn);
              if length(t_enn) <> 0 then
                begin
                  for i := 0 to High(t_enn) do
                    begin
                      myform._3D_device.Transform.World :=
                        myform._3D_device.Transform.World.Translation(t_enn[i].x,0,t_enn[i].y);
                      myform._3D_device.SetTexture(0, t_espion);
                      m_espion.DrawSubset(0);
                    end;
                end;
              myplayer.myreseauennemis.get_ennemi_by_typ('Kamikaze', t_enn);
              if length(t_enn) <> 0 then
                begin
                  for i := 0 to High(t_enn) do
                    begin
                      myform._3D_device.Transform.World :=
                        myform._3D_device.Transform.World.Translation(t_enn[i].x,0,t_enn[i].y);
                      myform._3D_device.SetTexture(0, t_kamikaze);
                      m_kamikaze.DrawSubset(0);
                    end;
                end;
              myplayer.myreseauennemis.get_ennemi_by_typ('Ennemi dynamique', t_enn);
              if length(t_enn) <> 0 then
                begin
                  for i := 0 to High(t_enn) do
                    begin
                      myform._3D_device.Transform.World :=
                        myform._3D_device.Transform.World.Translation(t_enn[i].x,0,t_enn[i].y);
                      myform._3D_device.SetTexture(0, t_warrior);
                      m_warrior.DrawSubset(0);
                    end;
                end;
            end;




      myform._3D_device.SetTexture(0, mymesh.plop.Texture);
      myform._3D_device.Transform.World := myform._3D_device.Transform.World.Translation((mymesh.plop.x), 0.1, (mymesh.plop.y));
      mymesh.plop.mesh.DrawSubset(0);




      myplayer.particle.Render_player(myform._3D_device);
      mymenu_in_game.render(myform._3D_device, myplayer.tab_contenu, myform.height, myform.width, myplayer.carac, mymesh.modif_tab_cont);
      mymenu_in_game.affiche_text_carac(myform.Width, myform.Height, myplayer.tab_contenu, myplayer.carac, mymenu.player_name);
      affiche_car_en;
      mymenu_in_game.find_param_bull(myform.m_x, myform.m_y, myform.Width, myform.Height, myplayer.tab_contenu);


      if myplayer.game_type='o' then
        begin
      //ici
          mysenar.affi_alli_selec(myform._width,myform._height,myplayer.selection_pos.exist,myplayer.selection_pos.t);
          if (quetelance)and(inhit) then
            mysenar.quete_inhit;
          mysenar.affiche_quete(myform._width,myform._height,myform._3D_device,myplayer);
          mysenar.attente(myplayer);
          myplayer.particle.render_level_up(myform._3D_device);
      end;

      if (myform.suppr = true) and (myplayer.arrive = true) and (myform.click_x >= 0) and (myform.click_x <= mymesh.taillex - 1) and (myform.click_y >= 0) and (myform.click_y <= mymesh.tailley - 1)  then
        begin
          if myplayer.game_type = 's' then
            myplayer.clientorserveur.send_del_obj(inttostr(myform.click_x), IntToStr(myform.click_y), IntToStr(myplayer.etage));
          if myplayer.game_type = 'c' then
            myplayer.clientorserveur.send_del_obj_client(IntToStr(myform.click_x), IntToStr(myform.click_y), IntToStr(myplayer.etage));
          mymesh.suppr_obj(myform.click_x, myform.click_y, 0, myplayer.tab_contenu );
          myplayer.arrive := false;
          myform.suppr := false;
        end;
      end;

      end;

    mygamemenu.affi_menu(myform.m_x, myform.m_y, myform.Width, myform.Height);
    mygamemenu.sur_bouton(myform.m_x, myform.m_y, myform.Width, myform.Height);
        end;





  myform._3D_device.EndScene;
  myform._3D_device.Present;

end;

//modif

procedure c_engine.affiche_mesh;
var
  i, j: integer;
  prout: string;
begin
  for j := 0 to length(mymesh.tab_mesh) - 1 do
    begin
      for i := 0 to length(mymesh.map2[myplayer.etage][j].tab_etage) - 1 do
        begin
          myform._3D_device.SetTexture(0, mymesh.tab_mesh[j].texture);
          myform._3D_device.Material := mymesh.tab_mesh[j].materials;
          if (mymesh.map2[myplayer.etage][j].objet.nom = 'none') or (mymesh.map2[myplayer.etage][j].objet.nom = 'Mur Rouge')then
            begin
             myform._3D_device.Transform.World := myform._3D_device.Transform.World.Translation(mymesh.map2[myplayer.etage][j].tab_etage[i].x, 0, mymesh.map2[myplayer.etage][j].tab_etage[i].y)
            end
          else
             if (mymesh.map2[myplayer.etage][j].objet.nom = 'Titou') then
              begin
                myform._3D_device.Transform.World :=
                myform._3D_device.Transform.World.RotationX(-pi / 2)*
                myform._3D_device.Transform.World.Translation(mymesh.map2[myplayer.etage][j].tab_etage[i].x, 0, mymesh.map2[myplayer.etage][j].tab_etage[i].y);
              end
          else
            if mymesh.map2[myplayer.etage][j].objet.nom = 'depart' then
              prout := ''
            else
              myform._3D_device.Transform.World := myform._3D_device.Transform.World.Translation(mymesh.map2[myplayer.etage][j].tab_etage[i].x, 0, mymesh.map2[myplayer.etage][j].tab_etage[i].y);
                                                   myform._3D_device.Transform.World.Translation(0,0.5,-0.5);
            mymesh.tab_mesh[j].mesh.DrawSubset(0);
        end;
    end;
end;

procedure c_engine.dispose;
begin
  mycam.Free;
  myinput.Free;
  mysound.Free;
  myform.Free;
  mymesh.Free;
  self.Free;
  myplayer.Free;
  mymenu.Free;
  myennemis.Free;
  mygamemenu.free;
  if not mymenu.show_menu then
    mymenu_in_game.prout;

end;

procedure c_engine.refresh_mobs;
var
  i: integer;
begin
  for i := 0 to myennemis.longueur(1) do
    begin
      mymesh.map2[myplayer.etage][myennemis.acces(i, 1).pos.x].tab_etage[myennemis.acces(i, 1).pos.y].x := myennemis.acces(i, 1).emplacement.x;
      mymesh.map2[myplayer.etage][myennemis.acces(i, 1).pos.x].tab_etage[myennemis.acces(i, 1).pos.y].y := myennemis.acces(i, 1).emplacement.y;
    end;
  for i := 0 to myennemis.longueur(2) do
    begin
      mymesh.map2[myplayer.etage][myennemis.acces(i, 2).pos.x].tab_etage[myennemis.acces(i, 2).pos.y].x := myennemis.acces(i, 2).emplacement.x;
      mymesh.map2[myplayer.etage][myennemis.acces(i, 1).pos.x].tab_etage[myennemis.acces(i, 1).pos.y].y := myennemis.acces(i, 1).emplacement.y;
    end;
  for i := 0 to myennemis.longueur(2) do
    begin
      mymesh.map2[myplayer.etage][myennemis.acces(i, 3).pos.x].tab_etage[myennemis.acces(i, 3).pos.y].x := myennemis.acces(i, 3).emplacement.x;
      mymesh.map2[myplayer.etage][myennemis.acces(i, 3).pos.x].tab_etage[myennemis.acces(i, 3).pos.y].y := myennemis.acces(i, 3).emplacement.y;
    end;


end;



procedure c_engine.affiche_car_en;
var
  tab: T_tabennemi;
begin
    if (myplayer.selection_pos.t = 'Kamikaze') and (myplayer.selection_pos.exist) then
    begin
      tab := myennemis.recu_tab(2);
      mymenu_in_game.affi_enne_selec(myform.Width,
                                     myform.Height,
                                     myplayer.selection_pos.exist,
                                     tab[myplayer.selection_pos.posj].vie.total,
                                     tab[myplayer.selection_pos.posj].vie.actuel,
                                     'Kamikaze');
    end;
  if (myplayer.selection_pos.t = 'Espion') and (myplayer.selection_pos.exist) then
    begin
      tab := myennemis.recu_tab(1);
      mymenu_in_game.affi_enne_selec(myform.Width,
                                     myform.Height,
                                     myplayer.selection_pos.exist,
                                     tab[myplayer.selection_pos.posj].vie.total,
                                     tab[myplayer.selection_pos.posj].vie.actuel,
                                     'Cypher');
    end;
  if (myplayer.selection_pos.t = 'Ennemi dynamique') and (myplayer.selection_pos.exist) then
    begin
      tab := myennemis.recu_tab(3);
      mymenu_in_game.affi_enne_selec(myform.Width,
                                     myform.Height,
                                     myplayer.selection_pos.exist,
                                     tab[myplayer.selection_pos.posj].vie.total,
                                     tab[myplayer.selection_pos.posj].vie.actuel,
                                     'Warrior');
    end;
end;


end.
